Function Get-VariableText
{
    Param(
        [Parameter(Mandatory = $True)]
        [String]
        $private:VariableName,
        
        [Parameter(Mandatory = $False)]
        [Object]
        $private:Variable = $Null,
        
        [Parameter(Mandatory = $False)]
        [System.Xml.XmlDocument]
        $private:Xml = $Null
    )
    
    Process
    {
        Function Get-X([System.Xml.XmlElement] $XmlElement, [Object] $Variable, [String] $VariableName)
        {
            $private:Str = ""
            $private:XmlPropertyNames = $XmlElement | Get-Member -MemberType Property | ForEach-Object { $_.Name }
            $private:VariablePropertyNames = $Variable | Get-Member -MemberType Property | ForEach-Object { $_.Name }
            $private:PropertyNamesUnion = Get-Join $XmlPropertyNames $VariablePropertyNames
            ForEach ($private:PropertyName in $PropertyNamesUnion)
            {
                $private:PropertyValue = [String]::Empty
                $private:TypeName = $Variable.$PropertyName.GetType().FullName
                $private:Interfaces = $Variable.$PropertyName.GetType().GetInterfaces()
                $private:IEnumerable = $Null
                If ($Interfaces -Ne $Null)
                {
                    $private:IEnumerable = $Interfaces | Where-Object { $_.Name -Eq "IEnumerable" }
                }
                
                If ($TypeName -Eq "System.Boolean")
                {
                    $private:PropertyValue = "`${0}" -f $XmlElement.$PropertyName
                }
                ElseIf ($TypeName -Eq "System.Int32")
                {
                    $private:PropertyValue = $XmlElement.$PropertyName
                }
                ElseIf ($TypeName -Eq "System.String")
                {
                    $private:PropertyValue = "`"{0}`"" -f $XmlElement.$PropertyName
                }
                ElseIf ($TypeName -Eq "System.Windows.Media.Color")
                {
                    $private:Color = $XmlElement.$PropertyName
                    $private:PropertyValue = "[System.Windows.Media.Color]`"#{0:X2}{1:X2}{2:X2}{3:X2}`"" -f ([int]$Color.A), ([int]$Color.R), ([int]$Color.G), ([int]$Color.B)
                }
                ElseIf ($IEnumerable -Ne $Null)
                {
                    ForEach ($private:KeyValuePair in $XmlElement.$PropertyName.ChildNodes)
                    {
                        $private:SubPropertyValue = [String]::Empty
                        $private:TypeName = $Variable.$PropertyName[$KeyValuePair.Key].GetType().FullName
                        If ($TypeName -Eq "System.Boolean")
                        {
                            $private:SubPropertyValue = "`${0}" -f $KeyValuePair.Value
                        }
                        ElseIf ($TypeName -Eq "System.Int32")
                        {
                            $private:SubPropertyValue = $KeyValuePair.Value
                        }
                        ElseIf ($TypeName -Eq "System.String")
                        {
                            $private:SubPropertyValue = "`"{0}`"" -f $KeyValuePair.Value
                        }
                        ElseIf ($TypeName -Eq "System.Windows.Media.Color")
                        {
                            $private:Color = $KeyValuePair.Value
                            $private:SubPropertyValue = "[System.Windows.Media.Color]`"#{0:X2}{1:X2}{2:X2}{3:X2}`"" -f ([int]$Color.A), ([int]$Color.R), ([int]$Color.G), ([int]$Color.B)
                        }
                        
                        $private:Str += ("{0}.{1}[`"{2}`"] = {3}; " -f $VariableName, $PropertyName, $KeyValuePair.Key, $SubPropertyValue)
                    }
                }
                
                If (-Not [String]::IsNullOrEmpty($PropertyValue))
                {
                    $private:Str += ("{0}.{1} = {2}; " -f $VariableName, $PropertyName, $PropertyValue)
                }
            }
            
            Return $Str
        }
    
        If ($VariableName -NotLike "`$*")
        {
            $private:VariableName = "`$" + $VariableName
        }
        
        If ($Variable -Eq $Null)
        {
            $private:Variable = Invoke-Command $ExecutionContext.InvokeCommand.NewScriptBlock($VariableName)
        }
        
        If ($Xml -Eq $Null)
        {
            $private:Xml = [Xml](Get-XmlString $Variable)
        }
        
        $private:XmlRootName = ($Xml | Get-Member -MemberType Property).Name

        $private:Text = Get-X $Xml.$XmlRootName $Variable $VariableName
        
        Return $Text
    }
}

Export-ModuleMember Get-VariableText
